﻿using Hypertek.IOffice.Common.Utilities;
using Hypertek.IOffice.Model;
using Hypertek.IOffice.Model.Entities;
using Hypertek.IOffice.Report.Excel;
using Hypertek.IOffice.Report.Excel.Table;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Hypertek.IOffice.Report.Layouts
{
    public class GenericExport : LayoutsPageBase
    {
        public List<T> GetItems<T>(SPList list) where T : BaseEntity
        {
            CAMLListQuery<T> query = new CAMLListQuery<T>(list);
            return query.ExecuteListQuery(string.Empty);
        }
        public byte[] GenerateExcel<T>(string sheetName, SPList list) where T : BaseEntity
        {
            List<T> datasources = this.GetItems<T>(list);
            byte[] buffer;
            using (MemoryStream ms = new MemoryStream())
            {
                using (ExcelPackage package = new ExcelPackage(ms))
                {
                    ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(sheetName);
                    worksheet.Cells["A1"].LoadFromCollection<T>(datasources, true, TableStyles.None);
                    package.Save();
                    buffer = ms.GetBuffer();
                }
            }
            return buffer;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            SPList list = SPContext.Current.List;
            EntityMapping mappings = EntityMapping.Instance();
            Type type = (Type)mappings[list.BaseTemplate.ToString()];
            Type listType = typeof(List<>);
            Type constructedListType = listType.MakeGenericType(new Type[]
			{
				type
			});
            IList instance = (IList)Activator.CreateInstance(constructedListType);
            MethodInfo method = base.GetType().GetMethod("GenerateExcel");
            MethodInfo generic = method.MakeGenericMethod(new Type[]
			{
				type
			});
            object data = generic.Invoke(this, new object[]
			{
				list.Title,
				list
			});
            if (data != null)
            {
                byte[] bytes = data as byte[];
                base.Response.Buffer = true;
                base.Response.Clear();
                base.Response.ClearHeaders();
                base.Response.ClearContent();
                string fileName = list.Title + ".xlsx";
                base.Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
                base.Response.AddHeader("Content-Type", "application/Excel");
                base.Response.ContentType = "application/vnd.xls";
                base.Response.BinaryWrite(bytes);
                base.Response.End();
            }
        }
    }
}
